﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace Adaptive_Clustering
{
    class Adaptive
    {

    Byte[,] ImageArray;
    Byte[,] ImageClusterIndexArray;
    int k, Sigma, Beta;
    bool EnableBilinear;
    MainGUI M_GUI;
        public Byte[,] GetImageArray() { return ImageArray; }
        public Byte[,] GetImageClusterIndexArray() { return ImageClusterIndexArray; }
        public Adaptive(Byte[,] ImageArray, Byte[,] ImageClusterIndexArray, int k, int Sigma, int Beta, MainGUI M_GUI, bool EnableBilinear)
        {
            this.ImageArray = ImageArray;
            this.ImageClusterIndexArray = ImageClusterIndexArray;
            this.k = k;
            this.Sigma = Sigma;
            this.Beta = Beta;
            this.M_GUI = M_GUI;
            this.EnableBilinear = EnableBilinear;
        }

        public void Adapt()
        {
            bool ImageIsConverged = false;
            int WindowSize;
            int Count = 0, CountMax = 10;
            double ProgressRatio = (double)(Constants.ProgressBarWhileInsensityDensity / (Math.Log(ImageArray.GetLength(0), 2) - 3));
            double ProgressCounter = M_GUI.ProcessImageProgressBar % Constants.ProgressBarMaxVal;
            WindowSize = ImageArray.GetLength(0); // set windowsize to image Width
            if (ImageArray.GetLength(0) > ImageArray.GetLength(1)) //if Width>Height
            {
                WindowSize = ImageArray.GetLength(1); // set windowsize to image Height
            }            
            while (WindowSize > 7)
            {
                while (!ImageIsConverged && Count < CountMax)
                {
                    Byte[,] NewImageArray = new Byte[ImageArray.GetLength(0), ImageArray.GetLength(1)];
                    Intensity intsty = new Intensity(EnableBilinear);
                    NewImageArray = intsty.intensity(ImageClusterIndexArray, ImageArray, k, WindowSize);
                    Distribution estDstrbtn = new Distribution(NewImageArray, ImageClusterIndexArray, k);
                    ImageClusterIndexArray = estDstrbtn.distribution(ImageClusterIndexArray, ImageArray, Sigma, Beta);
                    Count++;
                    ImageIsConverged = CheckImageConverged(NewImageArray, ImageArray);
                    if (!ImageIsConverged) ImageIsConverged = estDstrbtn.IsConverged();
                    ImageArray = NewImageArray;
                }
                Count = 0;
                ImageIsConverged = false;
                WindowSize /= 2;
                ProgressCounter += ProgressRatio;
                M_GUI.ProcessImageProgressBar = (int)(ProgressCounter % Constants.ProgressBarMaxVal);
            }
        }

        private bool CheckImageConverged(Byte[,] NewImageArray, Byte[,] ImageArray)
        {
        bool Converged = true;
        for (int i = 0; i < ImageArray.GetLength(0); i++)
            for (int j = 0; j < ImageArray.GetLength(1); j++)
                if (NewImageArray[i, j] != ImageArray[i, j])
                {
                    Converged = false;
                    break;
                }
        return Converged;
        }

        private Bitmap ConvertByteToBitmap(Byte[,] ImageArray)
        {
            int i_luma;
            int imageWidth = ImageArray.GetLength(0);
            int imageHeight = ImageArray.GetLength(1);
            Color newColor;
            Bitmap img = new Bitmap(imageWidth, imageHeight);
            //convert to image type
            for (int x = 0; x < imageWidth; x++)
            {
                for (int y = 0; y < imageHeight; y++)
                {
                    i_luma = (int)ImageArray[x, y];
                    newColor = Color.FromArgb(i_luma, i_luma, i_luma);
                    img.SetPixel(x, y, newColor);
                }
          
            }
            return img;
        }

    }

}

